cover image

Image processing (Numpy)¶

In this project, I'm applying a variety of techniques and methods to put into practice the skills I've acquired in image processing and manipulation.

Installing Required Libraries¶

In this code snippet, we address the requirements necessary for a specific task, which involve installing a set of essential libraries. To successfully execute certain operations, these libraries need to be present within the working environment.

To achieve this, the code utilizes the subprocess module to execute commands in the system's shell. It begins by defining a list named required_libraries, which enumerates the libraries that are vital for the intended task.

The subsequent steps involve iterating through this list and, for each library, invoking the pip install command to install it. The subprocess.check_call() function facilitates the execution of shell commands.

By running this code, you can ensure that all the essential libraries are properly installed in the environment, enabling you to perform the desired operations seamlessly.

In [ ]:
pip install subprocess
In [ ]:
pip install tensorflow
In [ ]:
import subprocess

# List of required libraries
required_libraries = [
    'numpy',
    'Pillow',
    'IPython',
    'opencv-python',
    'dlib',
    'avif-encode'
]

# Install the required libraries
for library in required_libraries:
    subprocess.check_call(['pip', 'install', library])

Discover Images Featuring Individuals¶

Let's search for pictures of people to use in this project, and you can explore the following websites to find images:

  1. Unsplash (https://unsplash.com)
  2. Pexels (https://www.pexels.com)
  3. Pixabay (https://pixabay.com)
  4. Freepik (https://www.freepik.com)
  5. Burst by Shopify (https://burst.shopify.com)
  6. Reshot (https://www.reshot.com)
  7. StockSnap (https://stocksnap.io)
  8. Rawpixel (https://www.rawpixel.com)

Script to Rename Portrait Images¶

The following code snippet is designed to facilitate the renaming of portrait images within a specified directory. The main purpose of this script is to organize and label portrait images in a consistent and sequential manner. The script scans through the given directory, identifies image files with extensions such as .jpg, .jpeg, .png, .gif, and .avif, and then renames them by prefixing them with "portrait_" followed by a unique sequential number.

Here's a brief overview of the code's functionality:

  1. The os module is imported to interact with the operating system.
  2. The rename_images function is defined, taking a directory path as its argument.
  3. The list of files within the specified directory is obtained using os.listdir(directory).
  4. Image files are filtered from the list based on common image file extensions.
  5. The filtered image files are sorted to ensure consistent numbering.
  6. A loop iterates through the sorted image files, and each file is renamed with a new filename containing the prefix "portrait_" and a sequential number.
  7. The old and new paths of each image file are constructed using os.path.join.
  8. The os.rename function is used to perform the renaming operation.
  9. A message is printed for each renamed file, displaying the original filename and the new filename.

To use the code, replace image_directory with the path to the directory containing the portrait images you wish to rename. The script will then execute, sequentially renaming the images and providing informative output about the renaming process.

In [ ]:
import os
def rename_images(directory):
    # Get the list of files in the directory
    files = os.listdir(directory)
    
    # Filter only image files (you can modify this condition based on your image file extensions)
    image_files = [file for file in files if file.endswith(('.jpg', '.jpeg', '.png', '.gif','.avif'))]
    
    # Sort the image files to ensure consistent numbering
    image_files.sort()
    
    # Rename the image files with sequential numbers
    for i, filename in enumerate(image_files, start=1):
        new_filename = f"portrait_{i}{os.path.splitext(filename)[1]}"
        old_path = os.path.join(directory, filename)
        new_path = os.path.join(directory, new_filename)
        os.rename(old_path, new_path)
        print(f"Renamed {filename} to {new_filename}")

# Specify the directory where the images are located
image_directory = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1'

# Call the function to rename the images
rename_images(image_directory)

Convert Images to PNG¶

Convert AVIF images to PNG format using a Python script with the avif library. Input AVIF file is decoded and transformed to RGB, then saved as PNG.

In [ ]:
import avif
import os

def convert_avif_to_png(avif_path, png_path):
    with open(avif_path, "rb") as f:
        avif_data = f.read()
    image = avif.Image.decode(avif_data)
    rgb_image = image.to_rgb().to_image()
    rgb_image.save(png_path, format="PNG")
    print(f"Image converted: {avif_path} -> {png_path}")

# Specify the AVIF input file path
avif_file = "input.avif"

# Specify the PNG output file path
png_file = "output.png"

# Call the conversion function
convert_avif_to_png(avif_file, png_file)

Apply Image Function¶

this function takes a directory of images and the name of the function to run, and then applies the specified function to each image: python

To Specify the directory where the images are located: </br> image_directory = '/path/to/images' </br>

To Specify the name of the function to run (e.g., 'image_invertor', 'image_to_black_and_white', etc.): </br> function_name = 'image_invertor' </br>

To Call the function to apply the specified function to all images in the directory: </br> apply_image_function(image_directory, function_name) </br>

In [1]:
import os

def apply_image_function(directory, function_name):
    # Get the list of files in the directory
    files = os.listdir(directory)

    # Filter only image files
    image_files = [file for file in files if file.endswith(('.jpg', '.jpeg', '.png', '.gif', '.avif'))]

    # Get the function to apply
    selected_function = globals().get(function_name)

    if selected_function is None:
        print("Function not found.")
        return

    # Apply the selected function to each image
    for file in image_files:
        image_path = os.path.join(directory, file)
        selected_function(image_path)

Image Invertor¶

This Python function, "image_invertor," is part of the "Image Inverter" project. The function takes an image file as input, inverts its colors using numerical operations and numpy arrays, and displays the modified image. By applying this function, you can easily transform the colors of an image, creating interesting visual effects or exploring different perspectives. It utilizes popular libraries such as PIL and numpy for image manipulation and representation.

In [2]:
def image_invertor(image_dir):
    import numpy as np
    from PIL import Image
    from IPython.display import display

    # Open the image using the avif PIL plugin
    image = Image.open(image_dir)
    
    # Convert the AVIF image to RGB format
    image = image.convert('RGB')

    # Convert the image to a NumPy array
    image_array = np.array(image)

    # Apply color inversion
    inverted_array = 255 - image_array

    # Create a PIL image from the inverted array
    inverted_image = Image.fromarray(inverted_array)

    # Display the inverted image
    display(inverted_image)
In [3]:
image_directory = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\PNG'
function_name = 'image_invertor'
apply_image_function(image_directory, function_name)

Person Image Processor¶

This function, person_image_processor, is designed to process images of people to make them visually appealing. It uses the PIL library for image manipulation and the IPython.display library to display the modified image.

To use this function, you need to provide the file path of the image as the argument image_dir.

In [4]:
def person_image_processor(image_dir):
    import numpy as np
    from PIL import Image, ImageFilter, ImageEnhance
    from IPython.display import display
    
    # Open the image
    image = Image.open(image_dir)
    
    # Apply image processing operations
    # Example: Convert the image to grayscale
    grayscale_image = image.convert("L")
    
    # Example: Apply a blur filter
    # blurred_image = grayscale_image.filter(ImageFilter.BLUR)
    
    # Example: Adjust the brightness
    # enhanced_image = ImageEnhance.Brightness(image).enhance(1.5)
    
    # Display the modified image
    display(grayscale_image)    
In [5]:
# example:

image_directory = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\PNG'
function_name = 'person_image_processor'
apply_image_function(image_directory, function_name)

Custom Artistic Transformation¶

The goal of the provided Python code is to perform a technique known as "artistic style transfer" between a content image and a style image. Artistic style transfer is a deep learning-based approach that aims to merge the content of one image with the artistic style of another image. In other words, it allows you to apply the visual characteristics and artistic elements of a style image to a content image, resulting in a new image that combines the content of one image with the aesthetics of another.

In [ ]:
import tensorflow as tf
import tensorflow_hub as hub
import numpy as np
from PIL import Image

def artistic_image_transform(content_image_path, style_image_path):
    # Load the content and style images
    content_image = tf.keras.preprocessing.image.load_img(content_image_path)
    style_image = tf.keras.preprocessing.image.load_img(style_image_path)

    # Preprocess the content and style images
    content_image = tf.keras.preprocessing.image.img_to_array(content_image)
    style_image = tf.keras.preprocessing.image.img_to_array(style_image)
    content_image = content_image / 255.0
    style_image = style_image / 255.0

    # Define the model for style transfer
    hub_module = hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2')
    model = hub.KerasLayer(hub_module)

    # Perform style transfer
    stylized_image = model(tf.convert_to_tensor(content_image), tf.convert_to_tensor(style_image))[0]

    # Convert the stylized image to PIL Image
    stylized_image = np.array(stylized_image) * 255
    stylized_image = stylized_image.astype(np.uint8)
    stylized_image = Image.fromarray(stylized_image)

    return stylized_image
In [ ]:
# Specify the path of the content and style images
content_image_path = r'content.jpg'
style_image_path = r'style.jpg'

# Call the artistic_image_transform function
output_image = artistic_image_transform(content_image_path, style_image_path)

# Display the output image
output_image.show()

Convert images to balck and white¶

In [7]:
def image_to_black_and_white(image_dir):
    from PIL import Image
    from IPython.display import display

    # Open the image
    image = Image.open(image_dir)

    # Convert the image to black and white
    black_and_white_image = image.convert("L")

    # Display the black and white image
    display(black_and_white_image)
In [8]:
# example:
image_directory = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\PNG'
function_name = 'image_to_black_and_white'
apply_image_function(image_directory, function_name)

Convert Images To Vectors

The goal of the provided Python code is to convert a given input image into a vector representation using edge detection and contour extraction techniques, and then save the resulting vector representation as an SVG (Scalable Vector Graphics) file.

In [13]:
import cv2
import numpy as np
import svgwrite

def image_to_vector(image_path, output_path):
    # Load the image
    image = cv2.imread(image_path)

    # Convert the image to grayscale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Perform edge detection
    edges = cv2.Canny(gray, 50, 150)

    # Find contours in the edge-detected image
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # Create a new SVG drawing
    dwg = svgwrite.Drawing(output_path + "/output.svg", profile='tiny')

    # Draw the contours as vector paths
    for contour in contours:
        points = [(float(point[0][0]), float(point[0][1])) for point in contour]
        dwg.add(dwg.polyline(points, fill='none', stroke='black'))

    # Save the SVG file
    dwg.save()

    print("Vector image saved as:", output_path + "/output.svg")
In [14]:
# Example:
image_directory = r'R:\Downloads\download.jpg'
output_directory = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\output_dir'
image_to_vector(image_directory, output_directory)
Vector image saved as: C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\output_dir/output.svg

Convert Images to Cartoon¶

convert a given input image into a cartoon-style image using a combination of image processing techniques, including grayscale conversion, edge detection, and filtering operations. The resulting cartoon-style image is then saved to the specified output directory.

In [15]:
def image_to_cartoon(image_dir, output_dir):
    import cv2
    import numpy as np
    from PIL import Image
    
    # Open the image
    image = cv2.imread(image_dir)
    
    # Convert the image to grayscale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    # Apply a median blur to reduce noise
    blurred = cv2.medianBlur(gray, 5)
    
    # Perform edge detection
    edges = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 9)
    
    # Apply bilateral filter to smoothen the image
    color = cv2.bilateralFilter(image, 9, 250, 250)
    
    # Combine the edges and color image
    cartoon = cv2.bitwise_and(color, color, mask=edges)
    
    # Save the cartoon image
    cartoon_path = output_dir + "/cartoon_image.jpg"
    cv2.imwrite(cartoon_path, cartoon)
    
    print("Cartoon image saved as:", cartoon_path)
In [17]:
# Example:
image_directory = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\png\portrait_4.png'
output_directory = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\output_dir'
image_to_cartoon(image_directory, output_directory)
Cartoon image saved as: C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\output_dir/cartoon_image.jpg

Enhance beauty¶

enhance the beauty of a given input image by applying a series of image processing operations, including bilateral filtering, contrast and brightness adjustment, and color correction. The resulting enhanced image is then saved to the specified output directory.

In [18]:
def enhance_beauty(image_dir, output_dir):
    import cv2
    import numpy as np
    
    # Load the image
    image = cv2.imread(image_dir)
    
    # Apply bilateral filter to smooth the image while preserving edges
    smoothed = cv2.bilateralFilter(image, 9, 75, 75)
    
    # Increase contrast and brightness
    enhanced = cv2.convertScaleAbs(smoothed, alpha=1.2, beta=10)
    
    # Adjust skin tones using color correction
    ycrcb = cv2.cvtColor(enhanced, cv2.COLOR_BGR2YCrCb)
    channels = list(cv2.split(ycrcb))
    channels[0] = cv2.equalizeHist(channels[0])
    ycrcb = cv2.merge(channels)
    corrected = cv2.cvtColor(ycrcb, cv2.COLOR_YCrCb2BGR)
    
    # Save the enhanced image
    enhanced_path = output_dir + "/enhanced_image.jpg"
    cv2.imwrite(enhanced_path, corrected)
    
    print("Enhanced image saved as:", enhanced_path)
In [19]:
# Example:
image_directory = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\png\portrait_3.png'
output_directory = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\output_dir'
enhance_beauty(image_directory, output_directory)
Enhanced image saved as: C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\output_dir/enhanced_image.jpg

Image Processing using Machine Learning Modles¶

Image Super-Resolution¶

This function enhances the resolution of an input image using the Enhanced Deep Super-Resolution (EDSR) model. The EDSR model is a deep learning-based approach that utilizes advanced techniques to generate high-resolution versions of low-resolution images.

The function takes an image as input and applies the pre-trained EDSR model to perform super-resolution. It upscales the image to a higher resolution while preserving and enhancing the details and sharpness. The resulting super-resolved image exhibits improved clarity and quality, making it ideal for various applications, such as image enhancement, zooming, or printing.

To use the function, provide the path to the input image and ensure the availability of the EDSR model file. The function leverages the TensorFlow library to load the model and applies it to the image. The output is a super-resolved image that is displayed or can be saved for further use.

the old way to do it¶

In this alternative approach, the function uses the OpenCV library to load the low-resolution image and perform super-resolution. The function converts the image to the YCrCb color space, extracts the Y channel (luma component), and upscales it using bilinear interpolation (cv2.resize) to achieve a 2x super-resolution.

The function then combines the super-resolved Y channel with the original Cr and Cb channels to form the super-resolved image in the YCrCb color space. Finally, it converts the super-resolved image back to the BGR color space for display purposes.

In [ ]:
import cv2
import numpy as np
import tensorflow as tf
import tensorflow_hub as hub

def image_super_resolution(image_path):
    # Load the low-resolution image using OpenCV
    lr_image = cv2.imread(image_path)

    # Convert the image from BGR to RGB
    lr_image_rgb = cv2.cvtColor(lr_image, cv2.COLOR_BGR2RGB)

    # Convert the image to float32 and normalize pixel values
    lr_image_float = lr_image_rgb.astype(np.float32) / 255.0

    # Load the ESRGAN generator model from TensorFlow Hub
    model = hub.load("https://tfhub.dev/captain-pool/esrgan-tf2/1")

    # Reshape the low-resolution image to match the model input shape
    lr_input = tf.expand_dims(lr_image_float, axis=0)

    # Generate the super-resolved image
    sr_output = model(lr_input)[0]

    # Rescale the output image pixel values to [0, 255]
    sr_output = ((sr_output + 1) / 2.0) * 255.0

    # Convert the image to uint8
    sr_image_rgb = sr_output.numpy().astype(np.uint8)

    # Convert the image from RGB to BGR
    sr_image_bgr = cv2.cvtColor(sr_image_rgb, cv2.COLOR_RGB2BGR)

    return sr_image_bgr
In [ ]:
# Specify the path of the input image
input_image_path = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\low_res_images\portrait_low_res_3.jpg'

# Call the image_super_resolution function
output_image = image_super_resolution(input_image_path)

# Display the output image
cv2.imshow('Output Image', output_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

the new way to do it using Deep Learning¶

In [ ]:
import tensorflow as tf
from PIL import Image

def image_super_resolution(image_path):
    # Load the pre-trained EDSR model
    model = tf.keras.models.load_model(r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\ML_pre_trained_models\EDSR_Tensorflow-master\models\EDSR_x2.pb')

    # Load and preprocess the input image
    image = tf.keras.preprocessing.image.load_img(image_path, target_size=(64, 64))
    image = tf.keras.preprocessing.image.img_to_array(image)
    image = image.astype('float32') / 255.0

    # Perform image super-resolution
    super_res_image = model.predict(tf.expand_dims(image, axis=0))[0]

    # Rescale the super-resolved image to 0-255 range
    super_res_image = tf.clip_by_value(super_res_image, 0.0, 1.0)
    super_res_image = tf.round(super_res_image * 255.0)
    super_res_image = tf.cast(super_res_image, tf.uint8)

    # Convert the super-resolved image to PIL Image
    super_res_image = tf.keras.preprocessing.image.array_to_img(super_res_image)

    return super_res_image

# Specify the path of the input image
input_image_path = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\images\course1_1\low_res_images\portrait_low_res_1'
# input_model_path = r'C:\Users\User\Desktop\GitHub-projects\projects\Data-Dives-Projects-Unleashed\ML_pre_trained_models\EDSR_Tensorflow-master\models\EDSR_x4.pb'

# Call the image_super_resolution function
output_image = image_super_resolution(input_image_path)

# Display the output image
output_image.show()

Conclusion:¶

In the journey of exploring the realm of image manipulation, I've embarked on a fascinating and creative path that has allowed me to delve into the captivating world of image manipulation. Through this project, I've had the opportunity to experiment with various techniques and tools that breathe new life into ordinary visuals, elevating them into something extraordinary.